/* Description: 信号量测试
 * Author: zhouhui
 * Release Date: 2014-09-02
 * Modify log: 
 */ 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>


sem_t *sp;
long sum;
int end;

void * tf(void *arg)
{
    char *str = arg;
    long cnt=0;
    for(;;)
    {
        if (sem_wait(sp) == -1)
        {
            perror("wait");
            return (void *)cnt;
        }
        cnt++;
//        printf("  %s: ALIVE %ld\n",str, cnt);
//        usleep(5000);
        if (end)
        {
            printf("thread %s end\n",str);
            break;
        }
    }
    return (void *)cnt;
}

int main(int argc, char **argv)
{
    sp =sem_open(argv[1],O_CREAT|O_RDWR, 0600, 0);
    if (sp == SEM_FAILED)
    {
        perror("sem_open");
        return 1;
    }

    pthread_t tid[argc];
    int i;
    for(i=3; i<argc; i++)
    {
        if(pthread_create(&tid[i],NULL,tf,argv[i]) != 0)
        {
            perror("create");
            return 1;
        }
    }

    int loop =atoi(argv[2]); 
    for(i=0;i<loop;i++)
    {
        if (sem_post(sp) == -1)
        {
            perror("post");
            return 1;
        }
        if (loop - i == argc - 3)
            end = 1;
        usleep(1000);
    }
    usleep(500000);
    printf("post: %d\n",i);

    void *retval;
    for(i=3;i<argc;i++)
    {
        pthread_join(tid[i], &retval);
        printf("**return %s: %ld\n",argv[i],(long)retval);
        sum += (long)retval;
    }

    printf("total: %ld\n",sum);
    return 0;
}
